package com.lagou.edu.factory;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Repository;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.utils.JavaScan;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.logging.Logger;

/**
 * @author 应癫
 *
 * 工厂类，生产对象（使用反射技术）
 */
public class BeanFactory {
    
    static Logger logger = Logger.getLogger(BeanFactory.class.getName());
    
    /**
     * 存储对象
     */
    private static Map<String, Object> beanMap = new HashMap<>();


    static {
    
        Map<String, Class<?>> classMap = new WeakHashMap<>();
        try {
            classMap = JavaScan.getClazzMap("com.lagou.edu");
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
    
        for (Map.Entry<String, Class<?>> entry : classMap.entrySet()) {
    
            Class<?> clazz = entry.getValue();
            Annotation serviceAnnotation = clazz.getAnnotation(Service.class);
            Annotation repositoryAnnotation = clazz.getAnnotation(Repository.class);
            if(serviceAnnotation!=null) {
                String classIdentity = ((Service) serviceAnnotation).value();
                if(classIdentity.equals("")) {
                    classIdentity = clazz.getSimpleName();
                }
                try {
                    beanMap.put(classIdentity, clazz.getDeclaredConstructor().newInstance());
                } catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                    logger.info(e.getMessage());
                }
            }
            if(repositoryAnnotation!=null) {
                String classIdentity = ((Repository) repositoryAnnotation).value();
                if(classIdentity.equals("")) {
                    classIdentity = clazz.getSimpleName();
                }
                try {
                    beanMap.put(classIdentity, clazz.getDeclaredConstructor().newInstance());
                } catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                    logger.info(e.getMessage());
                }
            }
        }
    
        for (Map.Entry<String, Object> entry : beanMap.entrySet()) {
        
            Object object = entry.getValue();
            Class<?> clazz =object.getClass();
            Field[] fieldArr = clazz.getDeclaredFields();
            for(int i=0; i<fieldArr.length; i++) {
                Field field =fieldArr[i];
                Annotation autowiredAnnotation = field.getAnnotation(Autowired.class);
                if(autowiredAnnotation!=null) {
                    Class<?> declaringClass = field.getType();
                    for (Map.Entry<String, Object> entry2 : beanMap.entrySet()) {
                        Object object2 = entry2.getValue();
                        if(declaringClass.isInstance(object2)) {
                            field.setAccessible(true);
                            try {
                                field.set(object, object2);
                            } catch (IllegalAccessException e) {
                                logger.info(e.getMessage());
                            }
                        }
                    }
                    
                }
            }
        }
        
    }


    // 任务二：对外提供获取实例对象的接口（根据id获取）
    public static  Object getBean(String id) {
        return beanMap.get(id);
    }

}
